package 细节.polymorphic多态;

public class 细节1 {//韩顺平309集
    public static void main(String[] args) {
        System.out.println("向上转型\n");
        //细节1、向上转型：父类的引用指向了子类对象
        Animal animal = new Cat(); //animal是父类Animal的引用，但指向了子类Cat的对象，所以animal的运行类型是Cat
        //细节2 语法：父类类型 引用 = new 子类对象()  同上;
        //object obj = new Cat();  这也可行，因为 object是父类Animal的父类，可以不是直接父类；

        //细节3：可以调用父类中的所有成员（需要遵守访问权限），不能调用子类特有的方法  即（可以调用子类中重写的方法）
        //虽然运行类型是Cat，但编译类型是Animal，所以不能调用子类特有的方法
        //animal.catchMouse(); //catchMouse()是子类特有的方法，编译错误，不能调用子类特有的方法

        animal.eat();//猫在吃鱼，
        //细节4：最终运行效果看子类的具体表现，
        //因为编译类型是Animal，所以编译器会加载Animal中的eat()方法，但运行时运行类型是Cat，所以会调用Cat重写父类的的eat()方法


        animal.eat();
        //编译时，是以编译类型(animal)来判断可用的方法，只能识别到父类的方法，而识别不到子类的方法，父类有什么方法就加载什么方法；
        // 运行时，他会从子类开始查找，如果子类有重写父类的方法，就调用子类的方法，没有就调用父类的方法
        animal.sleep();
        animal.show();
        animal.run();

        System.out.println("==================================");

        System.out.println("向下转型\n");
        //  Animal animal = new Cat()是调不了Cat的catchMouse()方法的
        //为了调用子类的catchMouse()方法，需要向下转型
        //细节1：语法：子类类型 引用 = (子类类型) 父类引用  ，只能强转父类的引用，不能强转父类的对象（重点）
        Cat cat = (Cat) animal;
        //编译类型：Cat   运行类型：Cat
        cat.catchMouse();//猫在抓老鼠，编译类型和运行类型都是：Cat
        cat.sleep();  //仍然可以使用父类的方法

        /**
         * 重中之重
         * {简单理解为运行类型不变，编译类型从父类转成子类
         * 父类类型 父类引用 = new 子类对象  （向上转型）
         * 子类类型 子类引用 = (子类类型) 父类引用  （向下转型）
         * }
         *
         * 父类的引用必须指向的是当前目标的对象（原先是什么对象，只能强转成该对象，比如animal原先指向Cat对象，你只能将animal强转成Cat）
         *
         * 1. Animal animal = new Cat();
         * 2. Cat cat = (Cat) animal;   （现在cat能调用自己和父类的方法，但animal还是只能调用自己的或子类中重写的方法打）
         * animal虽然编译类型是Animal，但运行类型是Cat，所以animal指向Cat对象；
         * 在向下转型时animal才能强转成Cat，给到cat；
         *
         * Dog dog = (Dog) animal;//编译报错
         * 因为animal原先指向Cat对象
         * 你不能把 Cat对象强转成Dog；
         */


    }
}

class Animal{
    String name = "动物";
    int age = 10;
    public void sleep(){
        System.out.println("动物在睡");
    }
    public void eat(){
        System.out.println("动物在吃");
    }
    public void run(){
        System.out.println("动物在跑");
    }
    public void show(){
        System.out.println("hello,你好");
    }
}


class Cat extends Animal{
    public void eat(){
        System.out.println("猫在吃鱼");
    }
    public void catchMouse(){
        System.out.println("猫在抓老鼠");
    }
}
